

#include "upgrade.h"
#include "crc32.h"
#include "flash_if.h"
#include "stdio.h"

void mcu_upgrade(void);


void wait_for_upgrade(void)
{
    //Enable_Upgrade_Receive();
    //FLASH_If_Erase(FLASH_UPLOAD_REGION_START_ADDR,FLASH_UPLOAD_REGION_PAGE_NUM);
    //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
    //mcu_upgrade();
    while(1);
}


/*
 * @brief : verify the packet receive from soc.
 * @param : packet data pointer
 * @param : packet length
 * @retval : verify result.
*/
#if 0
uint32_t packet_verify(uint8_t *data, uint32_t len)
{
    uint32_t cal_crc = 0;
    UpgradePacketHeader *pheader;
    
    pheader = (UpgradePacketHeader *)data;
    
	/* packet data size verify */
    if (len != PACKET_TOTAL_SIZE)
        return MCU_UPGRADE_PACKET_SIZE_ERROR;
    
	/* packet magic num verify */
    if (pheader->magic_num != PACKET_MAGIC_NUM)
        return MCU_UPGRADE_PACKET_MAGIC_ERROR;
	
	/* total packet num do not exceed half of mcu flash size */
	if (pheader->total_packet_num > PACKET_TOTAL_MAX_NUM)
		return MCU_UPGRADE_PACKET_TOTAL_NUM_ERROR;
    
	/* packet data crc32 verify */
    cal_crc = crc32(data + sizeof(UpgradePacketHeader), PACKET_DATA_SIZE);
    if (cal_crc != pheader->crc32)
        return MCU_UPGRADE_PACKET_CRC_ERROR;
    
    return MCU_UPGRADE_PACKET_VERIFY_OK;
}


void mcu_upgrade(void)
{
    uint16_t len = 0;
    uint8_t status  = 0;
    UpgradePacketHeader *pheader;
    uint8_t *p_source;
    uint8_t packet_num = 0;
    uint8_t total_packet_num = 255 ;
    uint32_t flash_addr = 0;
    static uint16_t write_num = 0;
    uint8_t ack = 0;
    
    while (1)
    {
        if (UART_RX_DMA_Status() & UART_RX_STAT_MASK)
        {
            /* get packet length */
            len = UART_RX_DMA_Status() & ~UART_RX_STAT_MASK;
            status = packet_verify(UART_RX_BUF,len);
            //HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2);
            if (status == MCU_UPGRADE_PACKET_VERIFY_OK)
            {
                pheader = (UpgradePacketHeader *)UART_RX_BUF;
                p_source = UART_RX_BUF + PACKET_HEADER_SIZE;
                packet_num = pheader->serial_num;
                total_packet_num =  pheader->total_packet_num;
                flash_addr = PACKET_DATA_SIZE * packet_num + FLASH_UPLOAD_REGION_START_ADDR;
                
                if (FLASH_If_Write(flash_addr, (uint64_t *)p_source, PACKET_DATA_SIZE / 8) \
                    == FLASH_WRITE_SUCCESS)
                {
                    write_num++;
                    ack = MCU_SEND_ACK;
                }
                else
                {
                    ack = MCU_WRITE_FLASH_ERROR;
                }
            }
            else
            {
                ack = MCU_VERIFY_PACKET_ERROR;
            }
            
            Serial_PutByte(ack);
            UART_RX_DMA_Status_Clear(); // clear transfer status.
            UART_RX_DMA_Enable(); // enable next dma transfer.
            
            if (total_packet_num == write_num) /* upgrade success */
            {
                printf("Upgrade done.\r\n");
                Disable_Upgrade_Receive();
                break;
            }
        }
    }
   
}
#endif
